package app.rpc.remote;

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

import app.core.AccessException;
import app.util.POJO;

/**
 * 远程基础类型
 * 
 * @author yiyongpeng
 * 
 */
public class RemoteType4Basic extends POJO implements RemoteType {

	@Override
	public boolean isValue() {
		return true;
	}
	
	public boolean isInterface() {
		return false;
	}

//	public Class<?> getTypeClass() {
//		if (clazz == null) {
//			switch (type) {
//			case TYPE_VOID:
//				clazz = void.class;
//				break;
//			case TYPE_BYTE:
//				clazz = byte.class;
//				break;
//			case TYPE_SHORT:
//				clazz = short.class;
//				break;
//			case TYPE_INT:
//				clazz = int.class;
//				break;
//			case TYPE_LONG:
//				clazz = long.class;
//				break;
//			case TYPE_FLOAT:
//				clazz = float.class;
//				break;
//			case TYPE_DOUBLE:
//				clazz = double.class;
//				break;
//			case TYPE_BOOLEAN:
//				clazz = boolean.class;
//				break;
//			case TYPE_CHAR:
//				clazz = char.class;
//				break;
//			default:
//				throw new AccessException("没有此类型的定义。");
//			}
//		}
//		return clazz;
//	}

	public void readExternal(ObjectInput in) throws IOException {
	}

	public void writeExternal(ObjectOutput out) throws IOException {
	}

	public RemoteType4Basic(Class<?> clazz) {
//		this.clazz = clazz;
		if (clazz == void.class) {
			type = (TYPE_VOID);
		} else if (clazz == byte.class) {
			type = (TYPE_BYTE);
		} else if (clazz == short.class) {
			type = (TYPE_SHORT);
		} else if (clazz == int.class) {
			type = (TYPE_INT);
		} else if (clazz == long.class) {
			type = (TYPE_LONG);
		} else if (clazz == float.class) {
			type = (TYPE_FLOAT);
		} else if (clazz == double.class) {
			type = (TYPE_DOUBLE);
		} else if (clazz == boolean.class) {
			type = (TYPE_BOOLEAN);
		} else if (clazz == char.class) {
			type = (TYPE_CHAR);
		} else if (clazz == String.class) {
			type = (TYPE_STRING);
		} else if (clazz == byte[].class) {
			type = (TYPE_BYTE_ARR1);
		} else if (clazz == short[].class) {
			type = (TYPE_SHORT_ARR1);
		} else if (clazz == int[].class) {
			type = (TYPE_INT_ARR1);
		} else if (clazz == long[].class) {
			type = (TYPE_LONG_ARR1);
		} else if (clazz == float[].class) {
			type = (TYPE_FLOAT_ARR1);
		} else if (clazz == double[].class) {
			type = (TYPE_DOUBLE_ARR1);
		} else if (clazz == boolean[].class) {
			type = (TYPE_BOOLEAN_ARR1);
		} else if (clazz == char[].class) {
			type = (TYPE_CHAR_ARR1);
		} else if (clazz == String[].class) {
			type = (TYPE_STRING_ARR1);
		} else if (clazz == String[][].class) {
			type = (TYPE_STRING_ARR2);
		} else {
			throw new IllegalArgumentException("not support: " + clazz);
		}
	}

	public void writeValue(Object value, ObjectOutput out) throws IOException {
		switch (type) {
		case TYPE_VOID:
			break;
		case TYPE_BYTE:
			out.writeByte((Byte) value);
			break;
		case TYPE_SHORT:
			out.writeShort((Short) value);
			break;
		case TYPE_INT:
			out.writeInt((Integer) value);
			break;
		case TYPE_LONG:
			out.writeLong((Long) value);
			break;
		case TYPE_FLOAT:
			out.writeFloat((Float) value);
			break;
		case TYPE_DOUBLE:
			out.writeDouble((Double) value);
			break;
		case TYPE_BOOLEAN:
			out.writeBoolean((Boolean) value);
			break;
		case TYPE_CHAR:
			out.writeChar((Character) value);
			break;
		case TYPE_STRING:
			out.writeUTF((String) value);
			break;
		case TYPE_BYTE_ARR1:
			byte[] barr = (byte[]) value;
			out.writeInt(barr.length);
			for(int i=0;i<barr.length;i++)
				out.writeByte(barr[i]);
			break;
		case TYPE_SHORT_ARR1:
			short[] sarr = (short[]) value;
			out.writeInt(sarr.length);
			for(int i=0;i<sarr.length;i++)
				out.writeShort(sarr[i]);
			break;
		case TYPE_INT_ARR1:
			int[] iarr = (int[]) value;
			out.writeInt(iarr.length);
			for(int i=0;i<iarr.length;i++)
				out.writeInt(iarr[i]);
			break;
		case TYPE_LONG_ARR1:
			long[] larr = (long[]) value;
			out.writeInt(larr.length);
			for(int i=0;i<larr.length;i++)
				out.writeLong(larr[i]);
			break;
		case TYPE_FLOAT_ARR1:
			float[] farr = (float[]) value;
			out.writeInt(farr.length);
			for(int i=0;i<farr.length;i++)
				out.writeFloat(farr[i]);
			break;
		case TYPE_DOUBLE_ARR1:
			double[] darr = (double[]) value;
			out.writeInt(darr.length);
			for(int i=0;i<darr.length;i++)
				out.writeDouble(darr[i]);
			break;
		case TYPE_BOOLEAN_ARR1:
			boolean[] blarr = (boolean[]) value;
			out.writeInt(blarr.length);
			for(int i=0;i<blarr.length;i++)
				out.writeBoolean(blarr[i]);
			break;
		case TYPE_CHAR_ARR1:
			char[] carr = (char[]) value;
			out.writeInt(carr.length);
			for(int i=0;i<carr.length;i++)
				out.writeChar(carr[i]);
			break;
		case TYPE_STRING_ARR1:
			String[] strarr = (String[])value;
			out.writeInt(strarr.length);
			for (int i = 0; i < strarr.length; i++) {
				out.writeUTF(strarr[i]);
			}
			break;
		case TYPE_STRING_ARR2:
			String[][] str2arr = (String[][])value;
			out.writeInt(str2arr.length);
			for (int i = 0; i < str2arr.length; i++) {
				String[] strs = str2arr[i];
				out.writeInt(strs.length);
				for (int j = 0; j < strs.length; j++) {
					out.writeUTF(strs[j]);
				}
			}
			break;
		default:
			throw new AccessException("没有此类型的定义。");
		}
	}

	/**
	 * 读返回值
	 * 
	 * @throws IOException
	 */

	public Object readValue(ObjectSession session, ObjectInput in) throws IOException {
		switch (type) {
		case TYPE_VOID:
			return null;
		case TYPE_BYTE:
			return in.readByte();
		case TYPE_SHORT:
			return in.readShort();
		case TYPE_INT:
			return in.readInt();
		case TYPE_LONG:
			return in.readLong();
		case TYPE_FLOAT:
			return in.readFloat();
		case TYPE_DOUBLE:
			return in.readDouble();
		case TYPE_BOOLEAN:
			return in.readBoolean();
		case TYPE_CHAR:
			return in.readChar();
		case TYPE_STRING:
			return in.readUTF();
		case TYPE_BYTE_ARR1:
			byte[]barr = new byte[in.readInt()];
			for(int i =0;i<barr.length; i++)
				barr[i]= in.readByte();
			return barr;
		case TYPE_SHORT_ARR1:
			short[]sarr = new short[in.readInt()];
			for(int i =0;i<sarr.length; i++)
				sarr[i]=  in.readShort();
			return sarr;
		case TYPE_INT_ARR1:
			int[]iarr = new int[in.readInt()];
			for(int i =0;i<iarr.length; i++)
				iarr[i]= in.readInt();
			return iarr;
		case TYPE_LONG_ARR1:
			long[]larr = new long[in.readInt()];
			for(int i =0;i<larr.length; i++)
				larr[i]=  in.readLong();
			return larr;
		case TYPE_FLOAT_ARR1:
			float[]farr = new float[in.readInt()];
			for(int i =0;i<farr.length; i++)
				farr[i]=  in.readFloat();
			return farr;
		case TYPE_DOUBLE_ARR1:
			double[]darr = new double[in.readInt()];
			for(int i =0;i<darr.length; i++)
				darr[i]=  in.readDouble();
			return darr;
		case TYPE_BOOLEAN_ARR1:
			boolean[]blarr = new boolean[in.readInt()];
			for(int i =0;i<blarr.length; i++)
				blarr[i]=  in.readBoolean();
			return blarr;
		case TYPE_CHAR_ARR1:
			char[]carr = new char[in.readInt()];
			for(int i =0;i<carr.length; i++)
				carr[i]=  in.readChar();
			return carr;
		case TYPE_STRING_ARR1:
			String[]strarr = new String[in.readInt()];
			for(int i =0;i<strarr.length; i++)
				strarr[i]=  in.readUTF();
			return strarr;
		case TYPE_STRING_ARR2:
			String[][]s2arr = new String[in.readInt()][];
			for(int i =0;i<s2arr.length; i++){
				s2arr[i]=  new String[in.readInt()];
				for (int j = 0; j < s2arr[i].length; j++) {
					s2arr[i][j] = in.readUTF();
				}
			}
			return s2arr;
		default:
			throw new AccessException("没有此类型的定义。");
		}
	}

	public String getName() {
		switch (type) {
		case TYPE_VOID:
			return void.class.getName();
		case TYPE_BYTE:
			return byte.class.getName();
		case TYPE_SHORT:
			return short.class.getName();
		case TYPE_INT:
			return int.class.getName();
		case TYPE_LONG:
			return long.class.getName();
		case TYPE_FLOAT:
			return float.class.getName();
		case TYPE_DOUBLE:
			return double.class.getName();
		case TYPE_BOOLEAN:
			return boolean.class.getName();
		case TYPE_CHAR:
			return char.class.getName();
		case TYPE_STRING:
			return String.class.getName();
		case TYPE_BYTE_ARR1:
			return byte[].class.getName();
		case TYPE_SHORT_ARR1:
			return short[].class.getName();
		case TYPE_INT_ARR1:
			return int[].class.getName();
		case TYPE_LONG_ARR1:
			return long[].class.getName();
		case TYPE_FLOAT_ARR1:
			return float[].class.getName();
		case TYPE_DOUBLE_ARR1:
			return double[].class.getName();
		case TYPE_BOOLEAN_ARR1:
			return boolean[].class.getName();
		case TYPE_CHAR_ARR1:
			return char[].class.getName();
		case TYPE_STRING_ARR1:
			return String[].class.getName();
		case TYPE_STRING_ARR2:
			return String[][].class.getName();
		default:
			throw new AccessException("没有此类型的定义。");
		}
	}

	public byte getType() {
		return type;
	}

	private byte type;

	// --------------------------------

	public static final int TYPE_VOID = 0;
	public static final int TYPE_BYTE = 1,TYPE_BYTE_ARR1 = 11;
	public static final int TYPE_SHORT = 2,TYPE_SHORT_ARR1 = 21;
	public static final int TYPE_INT = 3,TYPE_INT_ARR1 = 31;
	public static final int TYPE_LONG = 4,TYPE_LONG_ARR1 = 41;
	public static final int TYPE_FLOAT = 5,TYPE_FLOAT_ARR1 = 51;
	public static final int TYPE_DOUBLE = 6,TYPE_DOUBLE_ARR1 = 61;
	public static final int TYPE_BOOLEAN = 7,TYPE_BOOLEAN_ARR1 = 71;
	public static final int TYPE_CHAR = 8,TYPE_CHAR_ARR1 = 81;
	public static final int TYPE_STRING = 9, TYPE_STRING_ARR1=91, TYPE_STRING_ARR2=92;
	public static final int TYPE_OTHER = -1,TYPE_OTHER_ARR1 = 91;
}